# -*- coding: utf-8 -*-
import libreria, colore, classi
import time, urllib2, android, re
from BeautifulSoup import BeautifulSoup

droid = android.Android()

Horiz = "horizontal"
Vert = "vertical"
WrapC = "wrap_content"
FillP = "fill_parent"
MatcP = "match_parent"
ZeroDP = "0dp"

materie_slot = {}           #hash materia->dettagli per recuperare i dettagli associati alla materia/e selezionata/e
background_materie = {}     #hash materia->colore per recuperare il colore associato alla materia selezionata
id_materie_slot = {}        #hash id->materie per recuperare la materia associata all'id
materie_nuove = {}          #memorizzo le materie non presenti nel dizionario per assegnare i colori di background
materie_temp = {}           #hash usato per salvare momentaneamente le materie scelte in schermata_scelta_corsi
materie_def = {}            #hash usato per salvare definitivamente le materie scelte in schermata_scelta_corsi
count = 0                   #contatore usato per assegnare gli id in finestra_slot
cont = 1                    #contatore usato nella funzione navigazione
posizione = 0               #contatore di posizione durante la lettura della stringa in generazione_orario
url = {}                    #hash contenente tutti gli url delle pagine aperte inizialmente
url_specifiche = {}         #hash che assgna ad ogni id di ogni bottone l'url corrispondente da aprire 
menu_font = ""              #stringa utilizzata per memorizzare l'eventuale cambiamento del font durante l'esecuzione tramite il menu opzionale
font_cambiato = 0           #valore per ricordare che questo e' il font scelto all'ultima esecuzione dell'applicazione
cambiamenti = {             #hash che contiene i cambiamenti fatti con il menu opzionale
     "controllo_cambiamenti":0,
     "font":"",
     "corso_laurea":""
    }

#FUNZIONI USATE UNA VOLTA SOLA NEL PROGRAMMA
def inizializzazione_hash(temp): #inizializzo l'hash e le liste che gestiscono i corsi scelti nell'orario personalizzato
    global materie_temp, materie_def
    for i in range(0,3):
        materie_temp["lt%d" % (i+1)] = []
        materie_def["lt%d" % (i+1)] = []
        temp["lt%d" % (i+1)] = {}
    for i in range(0,2):
        materie_temp["lm%d" % (i+1)] = []
        materie_def["lm%d" % (i+1)] = []
        temp["lm%d" % (i+1)] = {}

def assegnamento(risp, temp, elenco, chiavi): #uso l'hash temp per inserire le materie scelte nell'orario personalizzato ma con la possibilità di cambiarle
    temp[risp] = {} #scelgo come posizione l'id dell'anno scelto
    for n in chiavi:
        if n in elenco.keys():
            temp[risp][n] = (elenco[n]) #inserisco nella posizione id le materie e gli url scelti
    return temp

def generazione_testo_orario(text): #suddivido text in righe e le inserisco in testo (ognuna in una posizione diversa)
    testo = []
    stringa = ""
    for l in text:
        if l != "\n":
            stringa = stringa + l
        else:
            stringa = stringa + "\n"
            testo.append(stringa)
            stringa = ""
    return testo

def recupero_materie(risp, corsi, dip): #recupero tutte le materie dell'anno scelto per l'orario personalizzato
    cod = corsi[risp + dip] #seleziono l'url dell'anno scelto 
    try: #leggo il contenuto della pagina dell'url selezionato e lo salvo in html
        page = urllib2.urlopen(cod, timeout = 5) 
        html = page.read()
        page.close()
    except IOError:
        elenco = rete_assente()
        return elenco
    try: #eseguo il parser per recuperare le materie dell'anno scelto con i loro url e salvo tutto in elenco
        elenco = parse_singole_materie(html) 
    except classi.ErroreFormato:
        s = classi.Stampe()
        s.messaggio_formato(droid)
        return 1
    except UnboundLocalError:
        time.sleep(1)
    return elenco

def modifica_stringa(string): #recupero tutte le informazioni contenute in string modificandola
    tmp = string.replace('$','')
    occorrenze_simbolo = tmp.count(';')
    tmp2 = tmp.replace(';','%',(occorrenze_simbolo-1))
    tmp3 = tmp2.replace(';','')
    tmp4 = tmp3.replace('\n','')
    tmp5 = tmp4.split('%')
    return tmp5

def cambiamento_font(): #cambio il font delle scritte
    global menu_font, cambiamenti, font_cambiato
    attr = classi.Attributi()
    menu_font = attr.scelta_font(droid, cambiamenti['font'], font_cambiato)
    if menu_font != "nothing":
        cambiamenti["controllo_cambiamenti"] = 1
        cambiamenti["font"] = menu_font
    
def mostra_aiuto(): #apro il menu di aiuto
    a = classi.Dialogo()
    a.Dialogo_menu_aiuto(droid)
         
#FUNZIONI USATE PIU' VOLTE NEL PROGRAMMA   
def rete_assente(): #controllo per la presenza della rete
    while True:
        try: #creo una finestra con scritto "Rete non trovata" e 2 bottoni per scegliere se rimanere nell'applicazione o uscire
            r = classi.Dialogo()
            ret = r.dialoghi(droid,classi.Dialogo.frase1,classi.Dialogo.frase2,
                       classi.Dialogo.frase3,0,classi.Dialogo.frasevuota,classi.Dialogo.frasevuota)
            if ret['which']=='positive':
                return 0
            elif ret['which']=='negative':
                return 1
        except KeyError:
            droid.makeToast(classi.Stampe.stampa1)

def creazione_slot(c, risp, length, dip, slot): #creo lo slot
    global count, materie_slot, url_specifiche, materie_nuove, url
    nome_materia = ""
    id_count = 0
    t1 = colore.Color.hexcode.items()
    for i in t1:
        if c == i[1]:
            nome_colore = i[0] #recupero il nome del colore associato al codice c
    t = classi.Inizializzazione()
    t2 = t.recupero_informazioni_corso_laurea(dip) #recupero tutti i colori associati alle materie di quel corso di laurea
    for j in t2:
        if nome_colore == j[1]:
            nome_materia = j[0] #recupero il nome della materia associata al colore nome_colore
    if nome_materia == "": #se la materia non c'è la vado a cercare in materie_nuove e le assegnerò il colore bianco
        if risp in materie_nuove.keys():
            nome_materia = materie_nuove[risp]
    nome = nome_materia.upper()
    dettagli = materie_slot[nome] #recupero i dettagli in materie_slot
    #creo un bottone per ogni dettaglio
    for x in dettagli:
        linear = libreria.LinearLayout("principale%s" % count,ZeroDP,FillP,
                                       {"background":colore.name("black"), "orientation":Horiz, "layout_weight":1})
        attr = classi.Attributi()
        gs = attr.grandezza_scrittura(length)
        det = libreria.Button("det%s" % count,MatcP,MatcP,{"text":"%s" % x, "textColor":colore.name("black"),
                              "textSize":gs, "background":colore.name(nome_colore), "layout_weight":1,
                              "textStyle":attr.text_style, "gravity":attr.gravity})
        y = x.replace('\n','')
        url_specifiche["det%s" % count] = url[y] #memorizzo in url_specifiche l'url corrispondente al bottone per poterlo parsificare nella funzione parser se questo viene cliccato
        linear.addView(det)
        slot.addView(linear) #aggiungo il bottone allo slot
        count += 1
        id_count += 1
    return slot

def aggiornamento_posizione(p, ids): #tengo memorizzata la posizione in cui mi trovo durante la creazione dell'orario per inserire le informazioni negli slot giusti
    global posizione
    posizione += 1
    if posizione == 4: #se sono arrivato a fine riga riparto da capo
        posizione = 0
        p = ids[0]
    else: #altrimenti restituisco la posizione in cui inserire il prossimo slot
        p = ids[posizione]
    return p

def gestione_Attributi(bottone, controllo): #gestisco gli Attributi assegnati a bottone per recuperare il valore del background
    att = bottone.translate_attrs()
    temp = att.replace('\n    ', '%')
    r = temp.split('%')
    if controllo == 0:
        res = r[len(r)-2].replace('android:background="#','')
    else:
        res = r[len(r)-1].replace('android:background="#','')
    res2 = res.replace('"','')
    res3 = res2.replace('\n','')
    result = res3.replace("f",'',2)
    return result

#FUNZIONI APPLICAZIONE
def schermata_iniziale(): #costruisco la schermata iniziale con i corsi di laurea
    global cambiamenti
    nc = ["CHIMICA","INFORMATICA","MATEMATICA","SCIENZE AMBIENTALI","SCIENZE BIOLOGICHE"]
    c = ["red","green","yellow","blue","violet"]
    v = libreria.LinearLayout("top1",FillP,FillP,{"background":colore.name("black"), "orientation":Vert})
    attr = classi.Attributi()
    #creo una textview con il titolo
    titol = libreria.TextView("title1",ZeroDP,FillP,
                  {"text":attr.frase_iniziale, "background":colore.name("blue"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]),
                   "gravity":attr.gravity, "layout_weight":1})
    v.addView(titol)
    #creo 5 bottoni per i corsi di laurea
    for r in range(0,5):
        row = libreria.LinearLayout("row%s" % r,ZeroDP,FillP,
                     {"background":colore.name(c[r]), "orientation":Horiz, "layout_weight":1})
        b = libreria.Button("dip%d" % r,MatcP,MatcP,{"text":"%s" % nc[r], "layout_weight":1, "gravity":attr.gravity,
                  "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
        b.setMargins(4,4,4,4,"dp")
        row.addView(b)
        v.addView(row)
    row = libreria.LinearLayout("bottom0",ZeroDP,FillP,
                     {"background":colore.name("black"), "orientation":Horiz, "layout_weight":1})
    # creo l'ultimo bottone per l'uscita dall'applicazione
    b = libreria.Button("fine0",MatcP,MatcP,{"text":attr.frase_uscita, "gravity":attr.gravity,
                  "background":colore.name("gray"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("black")})
    b.setMargins(4,4,4,4,"dp")
    row.addView(b)
    v.addView(row)
    return v

def schermata_scelta_tipo_orario(dip): #costruisco la schermata per scegliere l'anno
    global cambiamenti
    attr = classi.Attributi()
    td = attr.testo_corso_laurea(dip)
    v = libreria.LinearLayout("top2",FillP,FillP,
                     {"background":colore.name("black"), "orientation":Vert})
    #creo una textview con il nome del corso di laurea scelto come titolo
    t1 = libreria.TextView("title2",ZeroDP,FillP,{"text":td, "background":colore.name("blue"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]),
                           "gravity":attr.gravity, "layout_weight":1})              
    v.addView(t1)
    if dip == "dip0" or dip == "dip1" or dip == "dip3" or dip == "dip4": #se il corso di laurea scelto e' uno qualsiasi tranne matematica aggiungo i 3 anni della triennale 
        #creo 3 bottoni per gli anni della triennale
        for r in range(0,3):
            year = "I"*(r+1)
            row = libreria.LinearLayout("row%s" % (r+5),ZeroDP,FillP,
                     {"background":colore.name("red"), "orientation":Horiz, "layout_weight":1})
            b = libreria.Button("lt%d" % (r+1),MatcP,MatcP,
                                {"text":attr.frase_anno_triennale % year, "layout_weight":1, "gravity":attr.gravity,
                                 "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
            b.setMargins(4,4,4 if r==0 else 0,4,"dp")
            row.addView(b)
            v.addView(row)
    else: #se il corso di laurea scelto è matematica ho un solo anno
        row = libreria.LinearLayout("row5",ZeroDP,FillP,
                     {"background":colore.name("red"), "orientation":Horiz, "layout_weight":1})
        #creo il bottone per l'anno di matematica rimasto
        b = libreria.Button("lt3",MatcP,MatcP,{"text":attr.frase_terzo_anno, "layout_weight":1, "gravity":attr.gravity,
                            "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
        b.setMargins(4,4,4,4,"dp")
        row.addView(b)
        v.addView(row)
    if dip == "dip0" or dip == "dip1" or dip == "dip4": #se il corso di laurea o scelto è uno tra chimica, informatica e scienze biologiche devo aggiungere i 2 anni della magistrale
        #creo 2 bottoni per gli anni della magistrale
        for r in range(0,2):
            year = "I"*(r+1)
            row = libreria.LinearLayout("row%s" % (r+8),ZeroDP,FillP,
                     {"background":colore.name("yellow"), "orientation":Horiz, "layout_weight":1})
            b = libreria.Button("lm%d" % (r+1),MatcP,MatcP,{"text":attr.frase_anno_magistrale % year, "layout_weight":1,
                                "gravity":attr.gravity, "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
            b.setMargins(4,4,4 if r==0 else 0,4,"dp")
            row.addView(b)
            v.addView(row)
    row = libreria.LinearLayout("bottom1",ZeroDP,FillP,
                     {"background":colore.name("green"), "orientation":Horiz, "layout_weight":1})
    #creo il bottone per l'anno personalizzato
    b = libreria.Button("per",MatcP,MatcP,{"text":attr.frase_personalizzato, "gravity":attr.gravity,
                                           "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
    b.setMargins(4,4,4,4,"dp")
    row.addView(b)
    v.addView(row)    
    row = libreria.LinearLayout("bottom2",ZeroDP,FillP,
                     {"background":colore.name("black"), "orientation":Horiz, "layout_weight":1})
    #creo i 2 bottoni per il ritorno alla schermata precedente e per l'uscita dall'applicazione
    for i in range(0,2):
        tf = attr.testo_finale(i)
        b = libreria.Button("fine%d" % i,MatcP,MatcP,
                            {"text":tf, "layout_weight":1, "gravity":attr.gravity,
                             "background":colore.name("gray"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("black")})
        b.setMargins(4,4,4,4,"dp")
        row.addView(b)
    v.addView(row)
    return v

def decisione(droide, refresh, inizio): #funzione di gestione dei bottoni
    global menu_font
    while True:
        event=droid.eventWait().result
        if event["name"]=="click": #se l'evento è il click di un bottone
            ev=event["data"]["id"]
            droide.highlight(ev, "#ffffff") #highlight e return highlight funzioni per creare l'effetto del click
            droide.return_highlight(ev)
            return ev #ritorno l'id del bottone cliccato
        elif event["name"] == "font": #se l'evento e' il cambiamento del font lo cambio
            cambiamento_font()
            if refresh == 1 and menu_font != "" and menu_font != "nothing": #se sono in una delle pagine in cui si deve vedere il cambiamento faccio il refresh della stessa 
                droid.makeToast(classi.Stampe.stampa8)
            return "stai"
        elif event["name"] == "help": #se l'evento e' il mini-menu help lo apro 
            mostra_aiuto()
        elif event["name"] == "corso": #se l'evento e' il cambiamento del corso di laurea lo cambio
            if inizio == 1: #se mi trovo in un punto qualsiasi del programma (che non sia la schermata iniziale)
                return "partenza" #restituisco un stringa che mi permette di tornare a schermata_iniziale
            else:
                return "stai"
        elif event["name"] == "off": #se l'evento e' chiudi menu opzionale lo chiudo
            return "stai"
        elif event["name"]=="key": #se l'evento è il tasto back o il tasto menu
            ev=event["data"]["key"]
            if ev=="4":
                return "fine0" #ritorno lo stesso valore del bottone ritorna

def schermata_scelta_orario_personalizzato(dip): #costruisco la schermata con la scelta degli anni per l'orario personalizzato
    global cambiamenti
    attr = classi.Attributi()
    v = libreria.LinearLayout("top3",FillP,FillP,
                     {"background":colore.name("black"), "orientation":Vert})
    #creo una textview con titolo
    t1 = libreria.TextView("title3",ZeroDP,FillP,
                  {"text":attr.frase_scelta, "background":colore.name("blue"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]),
                   "gravity":attr.gravity, "layout_weight":1})              
    v.addView(t1)
    if dip == "dip0" or dip == "dip1" or dip == "dip3" or dip == "dip4": #se il corsoo di laurea scelto e' uno qualsiasi tranne matematica aggiungo i 3 anni della triennale 
        #creo 3 bottoni per gli anni della triennale
        for r in range(0,3):
            year = "I"*(r+1)
            row = libreria.LinearLayout("row%s" % (r+10),ZeroDP,FillP,
                     {"background":colore.name("red"), "orientation":Horiz, "layout_weight":1})
            b = libreria.Button("lt%d" % (r+1),MatcP,MatcP,
                                {"text":attr.frase_anno_triennale2 % year, "layout_weight":1, "gravity":attr.gravity,
                                 "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
            b.setMargins(4,4,4 if r==0 else 0,4,"dp")
            row.addView(b)
            v.addView(row)
    else: #se il corso di laurea scelto è matematica ho un solo anno
        row = libreria.LinearLayout("row10",ZeroDP,FillP,
                     {"background":colore.name("red"), "orientation":Horiz, "layout_weight":1})
        #creo il bottone per l'anno di matematica rimasto
        b = libreria.Button("lt3",MatcP,MatcP,{"text":attr.frase_terzo_anno2, "layout_weight":1, "gravity":attr.gravity,
                 "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
        b.setMargins(4,4,4,4,"dp")
        row.addView(b)
        v.addView(row)
    if dip == "dip0" or dip == "dip1" or dip == "dip4": #se il corso di laurea scelto è uno tra chimica, informatica e scienze biologiche devo aggiungere i 2 anni della magistrale
        #creo 2 bottoni per gli anni della magistrale
        for r in range(0,2):
            year = "I"*(r+1)
            row = libreria.LinearLayout("row%s" % (r+13),ZeroDP,FillP,
                     {"background":colore.name("yellow"), "orientation":Horiz, "layout_weight":1})
            b = libreria.Button("lm%d" % (r+1),MatcP,MatcP,
                                {"text":attr.frase_anno_magistrale2 % year, "layout_weight":1, "gravity":attr.gravity,
                                 "background":colore.name("black"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("white")})
            b.setMargins(4,4,4 if r==0 else 0,4,"dp")
            row.addView(b)
            v.addView(row)
    row = libreria.LinearLayout("bottom3",ZeroDP,FillP,
                     {"background":colore.name("black"), "orientation":Horiz, "layout_weight":1})
    #creo i 2 bottoni per il ritorno alla schermata precedente e per l'uscita dall'applicazione
    for i in range(0,2):
        tf = attr.testo_finale2(i)
        b = libreria.Button("fine%d" % i,MatcP,MatcP,
                            {"text":tf, "layout_weight":1, "gravity":attr.gravity,
                             "background":colore.name("gray"), "textSize":attr.scelta_grandezza_scrittura(cambiamenti["font"]), "textColor":colore.name("black")})
        b.setMargins(4,4,4,4,"dp")
        row.addView(b)
    v.addView(row)
    return v

def schermata_scelta_corsi(lista, risp): #scelgo i corsi per l'orario personalizzato
    global materie_temp, materie_def
    while True:
        try: #creo la finestra in cui inserire le materie che possono essere scelte
            r = classi.Dialogo() #scelgo le materie
            ret = r.dialoghi(droid,classi.Dialogo.frase4,classi.Dialogo.frase5,
                       classi.Dialogo.frase6,1,lista,materie_def[risp])
            if ret['which']=='positive': #se la risposta è ok
                materie_def[risp] = [] #svuoto sempre le materie che già avevo selezionato in un'altra esecuzione della funzione perchè potrei averne tolta qualcuna durante questa esecuzione
                materie_temp[risp] = droid.dialogGetSelectedItems().result
                for i in materie_temp[risp]: #prendo le materie scelte da materie_temp nella posizione dell'anno scelto
                    if i not in materie_def[risp]:
                        materie_def[risp].append(i) #inserisco le materie nella posizione dell'anno scelto
                break
            elif ret['which']=='negative': #se la risposta è annulla esco dalla funzione senza salvare le modifiche
                return 'annulla'
        except KeyError:
            droid.makeToast(classi.Stampe.stampa2)
    materie_temp[risp] = [] #cancello le materie appena selezionate dall'hash temporaneo 
    return materie_def[risp]

def parse_singole_materie(s): #recupero gli url di tutte le materie dell'anno selezionato
    global url
    materie = {}
    soup = BeautifulSoup(s) #inizio il parsing
    righe = soup.tbody.findAll('tr')
    if(len(righe)!=5):
        raise classi.ErroreFormato()
    for r in righe:
        slots = r.findAll('td')
        if(len(slots)!=4):
            raise classi.ErroreFormato()
        for i in range(4):
            tag = slots[i].findAll(href=re.compile('modulo')) #recupero gli url delle materie
            tag2 = slots[i].findAll(href=re.compile('html')) #recupero tutti gli url presenti
            if(tag is None):
                break
            else:
                for j in tag:
                    if j.contents[0] not in materie.keys(): #j.contents[0] contiene il nome della materia
                        materie[j.contents[0]] = classi.Indirizzo.ind + j['href'].strip('..') #associo alla materia l'url appropriato
            if(tag2 is None):
                break
            else:
                for k in tag2:
                    if k.contents[0] not in url.keys(): #k.contents[0] contiene il nome della materia/docente/aula
                        url[k.contents[0]] = classi.Indirizzo.ind + k['href'].strip('..') #associo alla materia/docente/aula l'url appropriato
    return materie

def parse_orario(ris): #recupero le informazioni delle materie selezionate
    global url
    giorni = ["Lu", "Ma", "Me", "Gi", "Ve"] #inizializza hash che associa le materie ai giorni
    materie = {}
    day = 0
    contatore = 0
    for g in giorni:
        materie[g] = [] #in materie inserisco come chiavi i giorni
    for cod in ris.values(): #per tutti gli url in ris
        try: #leggo la pagina associata all'url cod
            page = urllib2.urlopen(cod, timeout = 5)
            html = page.read()
            page.close()
        except IOError:
            output = rete_assente()
            return output
        soup = BeautifulSoup(html) #inizio il parsing
        righe = soup.tbody.findAll('tr')
        if(len(righe)!=5):
            raise classi.ErroreFormato
        for r in righe:
            slots = r.findAll('td')
            if(len(slots)!=4):
                raise classi.ErroreFormato()
            for i in range(4):
                t = slots[i].findAll(text=re.compile('\w')) #leggo tutta la parte testuale che contiene t
                tag = slots[i].findAll(href=re.compile('html')) #leggo tutti gli url della pagina
                if(tag is None):
                    break
                else:
                    for k in tag:
                        if k.contents[0] not in url.keys(): #memorizzo tutti gli url letti prima
                            url[k.contents[0]] = classi.Indirizzo.ind + k['href'].strip('..')
                if(len(t)<=0):
                    raise classi.ErroreFormato()
                if len(t)==1:
                    if(t[0]!="&nbsp;"):
                        raise classi.ErroreFormato()
                    if contatore == 0:
                        materie[giorni[day]].append(t[0]) #aggiungo la stringa "&nbsp;" al giorno in cui mi trovo
                else:
                    if(len(t)%3!=0):
                        raise classi.ErroreFormato()
                    if contatore == 0: #se nella stringa non c'e' nulla
                        materie[giorni[day]].append("%".join(t) + ";") #aggiungo la stringa con la materia al giorno appropriato
                    else: #se invece c'e' gia' qualcosa
                        if materie[giorni[day]][i] == "&nbsp;": #se c'e' "&nbsp;" lo rimuovo e inserisco la stringa con la materia
                            del materie[giorni[day]][i]
                            materie[giorni[day]].insert(i,"%".join(t) + ";")
                        else: #altrimenti se c'e' gia' una stringa con una o piu' materie ci unisco quella nuova
                            temp = []
                            temp.append("$")
                            temp.append(materie[giorni[day]][i])
                            temp.append("%".join(t) + ";")
                            s = ''.join(temp)
                            del materie[giorni[day]][i]
                            materie[giorni[day]].insert(i,s)
            day = day + 1
        contatore = contatore + 1
        day = 0
    output = "" #il risultato contenuto in materie lo inserisco nella stringa output e ritorno quest'ultima
    for g in giorni:
        output += g + "\n"
        for r in materie[g]:
            output += r + "\n"
    return output

def orario_singolo_anno(cod, dip): #genero l'orario classico(non personalizzato)
    try: #leggo il codice della pagina corrispondente e lo salvo in html
        page = urllib2.urlopen(cod, timeout = 5)
        html = page.read()
        page.close()
    except IOError: #se non c'e'la rete parte l'eccezione
        alert = rete_assente()
        return alert
    try: #eseguo il primo parser per recuperare le materie dell'anno scelto con i loro url e salvo tutto in lista
        lista = parse_singole_materie(html)
    except classi.ErroreFormato: #se c'e' un errore durante il parsing parte l'eccezione ErroreFormato
        s = classi.Stampe()
        s.messaggio_formato(droid)
        return 1
    try: #eseguo il secondo parser per recuperare l'orario dagli url di tutte le materie salvati in lista e lo salvo in output
        output = parse_orario(lista)
    except classi.ErroreFormato:
        s = classi.Stampe()
        s.messaggio_formato(droid)
        return 1
    if output == 0 or output == 1:
        return output
    pn = prima_navigazione(output, dip) #ora che ho l'orario lo genero in prima_navigazione
    return pn
                    
def orario_personalizzato(corsi, dip): #genero l'orario personalizzato
    elenco = {}             #hash contenente tutti gli url delle materie dell'anno selezionato 
    risultato = {}          #hash contenente gli url delle materie selezionate
    temporaneo = {}         #hash temporaneo contenente gli url delle materie selezionate ma non ancora definitive
    nomi_corsi = []         #lista contenente i nomi di tutte le materie dell'anno selezionato
    chiavi = []             #lista contenente i nomi delle materie selezionate
    stato_intermedio = 0    #valore impostato quando ho l'orario personalizzato completo
    inizializzazione_hash(temporaneo) #inizializzo le liste materie_temp e materie_def che userò in schermata_scelta_corsi e anche l'hash temporaneo usato per mantenere gli url delle materie selezionate ma non ancora definitive
    try: #controlla se e' presente un file già creato in un'esecuzione precedente dell'applicazione
        o = classi.GestioneFile()
        out = o.lettura_file(dip) #leggo gli url (e le materie) gia' selezionati in una esecuzione precedente dell'applicazione 
        if len(out) != 0: #se il file e' presente e non e' vuoto chiedo se si vuole rivedere l'orario
            while True:
                try:
                    r = classi.Dialogo()
                    ret = r.dialoghi(droid,classi.Dialogo.frase7,classi.Dialogo.frase8,
                               classi.Dialogo.frase9,2,out.keys(),classi.Dialogo.frasevuota)
                    if ret['which']=='positive': #se scelgo si rivedo l'orario finale
                        ris = orario_esistente(out, dip)
                        if ris == 1 or ris == 2:
                            return ris
                        while True: #ora chiedo se si vuole creare un nuovo orario
                            try:
                                r = classi.Dialogo()
                                ret = r.dialoghi(droid,classi.Dialogo.frase10,classi.Dialogo.frase8,
                                           classi.Dialogo.frase9,0,classi.Dialogo.frasevuota,classi.Dialogo.frasevuota)
                                if ret['which']=='positive': #se rispondo si ne creo uno nuovo
                                    o.cancellazione_file(dip)
                                    break
                                else: #se rispondo no chiudo l'applicazione
                                    return 1
                            except KeyError:
                                droid.makeToast(classi.Stampe.stampa3)
                        break
                    elif ret['which']=='negative': #se scelgo no lo cancello automaticamente e proseguo con l'esecuzione
                        o.cancellazione_file(dip)
                        break
                    out = {}
                except KeyError:
                    droid.makeToast(classi.Stampe.stampa3)
    except (EOFError, IOError): #errori durante la lettura del file (EOFError = errore di lunghezza del file, IOError = errore assenza file)
        droid.makeToast(classi.Stampe.stampa4)
        time.sleep(1)
    while True: #ora devo selezionare quale anno mi interessa per il mio orario personalizzato
        scelta = schermata_scelta_orario_personalizzato(dip)
        scelta.show(droid)
        risp = decisione(scelta, 1, 1) #decido cosa fare nella schermata
        if risp == "fine1": #se ho schiacciato il bottone genera
            if stato_intermedio == 1: #se ho scelto le materie che mi interessano genero l'orario
                for p in temporaneo: #inserisco in risultato tutte le materie scelte (che erano in temporaneo)
                    for q in temporaneo[p]:
                        risultato[q] = temporaneo[p][q]
                scr = classi.GestioneFile() 
                scr.scrittura_file(risultato, dip) #memorizzo gli url (e le materie) selezionati in un file (per una successiva esecuzione dell'applicazione)
                try: #eseguo il parser per recuperare l'orario dagli url di tutte le materie salvati in risultato e lo salvo in output
                    output = parse_orario(risultato)
                except classi.ErroreFormato:
                    s = classi.Stampe()
                    s.messaggio_formato(droid)
                    return 1
                if output == 0 or output == 1:
                    return 1
                pn = prima_navigazione(output, dip) #ora che ho l'orario lo genero in prima_navigazione
                return pn
            else: #non ho ancora scelto alcuna materia
                droid.makeToast(classi.Stampe.stampa5)
                continue
        elif risp == "fine0": #se ho schiacciato il bottone ritorna o il tasto back torno a schermata_scelta_tipo_orario 
            temporaneo = {}
            return 0
        elif risp == "stai":
            continue
        elif risp == "partenza":
            return 2
        else: #se ho schiacciato uno dei bottoni degli anni
            elenco = recupero_materie(risp, corsi, dip) #inserisco in elenco tutte le materie dell'anno selezionato con relativi url
            if elenco == 0:
                continue
            elif elenco == 1:
                return 1
            else: #se ho delle materie in elenco
                for i in elenco.keys(): #recupero il nome delle materie di elenco e le inserisco in nomi_corsi
                    nomi_corsi.append(i)  
                materie_selezionate = schermata_scelta_corsi(nomi_corsi, risp) #inserisco in materie_selezionate le materie scelte
                if materie_selezionate == 'annulla': #se ho schiacciato annulla tolgo tutte le modifiche fatte durante l'ultima esecuzione di schermata_scelta_corsi
                    nomi_corsi = []
                    continue
                else: #se ho schiacciato ok
                    chiavi = []
                    for j in materie_selezionate: #inserisco in chiavi i nomi delle materie selezionate in schermata_scelta_corsi
                        chiavi.append(nomi_corsi[j])
                    temporaneo = assegnamento(risp, temporaneo, elenco, chiavi) #inserisco in temporaneo gli url delle materie scelte ma non ancora definitive
                    stato_intermedio = 1
                    nomi_corsi = []


def orario_esistente(lista, dip): #mostro l'orario gi� selezionato in un'altra esecuzione dell'applicazione
    try:
        output = parse_orario(lista) #parsifico le pagine indicate dagli url contenuti in lista
    except classi.ErroreFormato:
        s = classi.Stampe()
        s.messaggio_formato(droid)
        return 1
    if output == 0 or output == 1:
        return output
    pn = prima_navigazione(output, dip) #ora che ho l'orario lo genero in prima_navigazionehghk-
    return pn

def generazione_orario(text, dip): #generazione tabella per visualizzare l'orario
    global materie_slot, background_materie, id_materie_slot, materie_nuove, posizione
    id_ora = ["ora1","ora2","ora3","ora4"]
    ore = {}
    i = 0
    k = 0
    j = 1
    pos = id_ora[0]
    temporaneo = []
    attr = classi.Attributi()
    #creo un LinearLayout verticale di base chiamato xml
    xml = libreria.LinearLayout("one",FillP,FillP,
                     {"background":colore.name("black"), "orientation":Vert})
    #creo un LinearLayout orizzontale per i giorni chiamato nomigiorni
    nomigiorni = libreria.LinearLayout("two",ZeroDP,FillP,
                     {"orientation":Horiz, "layout_weight":2})
    #creo 4 LinearLayout orizzontali per le ore
    for ids in id_ora:
        ore[ids] = libreria.LinearLayout("hour%s" % j,ZeroDP,FillP,
                     {"orientation":Horiz, "layout_weight":3})
        j += 1
    #creo un LinearLayout orizzontale per i bottonichiamato bottoni
    bottoni = libreria.LinearLayout("three",ZeroDP,FillP,
                     {"orientation":Horiz, "layout_weight":2})
    #aggiungo a nomigiorni una textview vuota
    nomigiorni.addView(libreria.TextView("boxempty",FillP,ZeroDP,{"text":attr.frase_vuota, "background":colore.name("red"), "gravity":attr.gravity, "layout_weight":1}))
    #aggiungo ai LinearLayout delle ore le textview con le ore
    j = 1
    for obj in ore.values():
        obj.addView(libreria.TextView("ora%s" % j,FillP,ZeroDP,{"text":attr.testo_ore(j), "textColor":colore.name("white"), "background":colore.name("red"),
                                   "gravity":attr.gravity, "layout_weight":1}))
        j += 1
    testo = generazione_testo_orario(text) #traduco text in una lista di stringhe e la salvo in testo
    for linea in testo: #scorro la lista
        if linea=="Lu\n" or linea=="Ma\n" or linea=="Me\n" or linea=="Gi\n" or linea=="Ve\n": #se la stringa contiene il nome del giorno lo inserisco in nomigiorni
            lin = linea.replace("\n","")
            bg = attr.background_giorni(lin)
            nomigiorni.addView(libreria.TextView("boxday%s" % i,FillP,ZeroDP,
                                        {"text":lin, "textColor":colore.name("white"), "background":colore.name(bg),
                                         "textStyle":attr.text_style, "gravity":attr.gravity, "layout_weight":2}))
            i += 1
            posizione = 0
        elif linea == "&nbsp;\n": #se la stringa contiene "&nbsp;\n" inserisco nella posizione in cui mi trovo una textview vuota
            ore[pos].addView(libreria.TextView("boxempty%s" % i,FillP,ZeroDP,
                                    {"text":attr.frase_vuota, "layout_weight":2}))
            pos = aggiornamento_posizione(pos, id_ora) #aggiorno la posizione nella mia tabella
            i += 1
        elif linea[0] == "$": #se la stringa contiene piu' materie
            materia = modifica_stringa(linea) #recupero tutti i dettagli
            lunghezza = len(materia)/3 #conto quante materie sono
            conto = 0
            #creo una LinearLayout per tutti i bottoni che creero chiamato base
            base = libreria.LinearLayout("base%s" % i,MatcP,ZeroDP,
                     {"background":colore.name("white"), "orientation":Vert, "layout_weight":2})
            for h in materia:
                if (conto % 3) == 0: #se leggo il nome della materia
                    decodifica = h.encode("utf-8") #recupero il nome della materia
                    materie_slot[decodifica] = []
                    materie_slot[decodifica].append(h) #nella chiave corrispondente al nome della materia inserisco il nome come primo dettaglio
                    if lunghezza >= 4:
                        gs = attr.grandezza_scrittura(4)
                    else:
                        gs = attr.grandezza_scrittura(2)
                    #creo il bottone corrispondente alla materia e lo aggiungo a base
                    bottone = libreria.Button("button%s%s" % (i,k),(98/lunghezza),MatcP,
                                        {"text":decodifica[0], "textColor":colore.name("black"), "layout_weight":2, "textSize":gs,
                                         "background":classi.associazione(decodifica, dip), "gravity":attr.gravity})
                    base.addView(bottone)
                    temporaneo.append("button%s%s" % (i,k)) #inserisco in temporaneo l'id del bottone creato
                    result = gestione_Attributi(bottone, 0) #recupero il colore di background associato a quella materia
                    if result == "ffffff": #se il colore e' bianco allora la materia non e' del corso di laurea scelto allora lo memorizzo in materie_nuove
                        materie_nuove["button%s%s" % (i,k)] = decodifica
                    background_materie["button%s%s" % (i,k)] = result #altrimenti memorizzo il background corrispondente al bottone
                    k += 1
                else:
                    materie_slot[decodifica].append(h) #nella chiave corrispondente al nome della materia inserisco il dettaglio
                conto += 1
            for q in temporaneo: #memorizzo in id_materie_slot tutti i dettagli dei bottoni appena creati cosi in questo slot qualunque bottone schiacci mi compaiono sempre tutti i dettagli
                id_materie_slot[q] = [] 
                for p in temporaneo:
                    id_materie_slot[q].append(p)
            #aggiungo base nel LinearLayout giusto
            ore[pos].addView(base)
            pos = aggiornamento_posizione(pos, id_ora) #aggiorno la posizione nella mia tabella
            i += 1
            temporaneo = []
        else: #se la stringa contiene una sola materia
            tmp = linea.replace(';','')
            materia = tmp.split('%')
            decodifica = materia[0].encode("utf-8") #recupero il nome della materia
            materie_slot[decodifica] = []
            for m in materia:
                materie_slot[decodifica].append(m) #memorizzo i dettagli corrispondenti alla materia
            #creo il bottone
            bottone = libreria.Button("e%s" % i,FillP,ZeroDP,
                            {"text":decodifica[0], "layout_weight":2, "gravity":attr.gravity, "textColor":colore.name("black"),
                             "background":classi.associazione(decodifica, dip)})
            id_materie_slot["e%s" % i] = "e%s" % i #memorizzo in id_materie_slot l'id del bottone (per capire poi in finestra_slot se qui c'e' una sola materia o di piu')
            result = gestione_Attributi(bottone, 1) 
            if result == "ffffff":
                materie_nuove["e%s" % i] = decodifica
            background_materie["e%s" % i] = result
            ore[pos].addView(bottone)
            pos = aggiornamento_posizione( pos, id_ora)
            i += 1
    xml.addView(nomigiorni) #aggiungo a xml nomigiorni
    for obj in ore.values(): #aggiungo a xml tutti i LinearLayout con gli slot
        xml.addView(obj)
    #aggiungo i 2 bottoni per il ritorno alla schermata precedente o per l'uscita dall'applicazione al LinearLayout bottoni
    for i in range(0,2):
        tf = attr.testo_finale(i)
        b = libreria.Button("fine%d" % i,MatcP,MatcP,{"text":tf, "layout_weight":1,
                 "gravity":attr.gravity, "background":colore.name("gray"), "textColor":colore.name("black")})
        bottoni.addView(b)
        b.setMargins(4,4,4,4,"dp")
    xml.addView(bottoni) #aggiungo a xml bottoni
    return xml

def finestra_slot(risp, dip): #finestra con i dettagli dello slot cliccato
    attr = classi.Attributi()
    global count, background_materie, id_materie_slot
    #aggiungo un LinearLayout verticale principale chiamato slot
    slot = libreria.LinearLayout("principale",FillP,FillP,
                     {"background":colore.name("black"), "orientation":Vert})
    if id_materie_slot[risp] == risp: #se lo slot contiene una sola materia
        c = background_materie[risp] #recupero il codice del colore di background associato alla materia
        slot = creazione_slot(c, risp, 1, dip, slot) #creo lo slot
    else: #se lo slot contiene piu' materie
        length = len(id_materie_slot[risp])
        for m in id_materie_slot[risp]: #creo uno slot per ogni materia
            c = background_materie[m]
            slot = creazione_slot(c, risp, length, dip, slot)
    linear = libreria.LinearLayout("principale%s" % count,ZeroDP,FillP,
                    {"background":colore.name("black"), "orientation":Horiz, "layout_weight":1})
    count += 1
    #aggiungo i 2 bottoni per il ritorno alla schermata precedente o per l'uscita dall'applicazione
    for h in range(0,2):
        tf = attr.testo_finale(h)
        b = libreria.Button("fine%d" % h,MatcP,MatcP,
                            {"text":tf, "gravity":attr.gravity, "layout_weight":1,
                             "background":colore.name("gray"), "textColor":colore.name("black")})
        b.setMargins(4,4,4,4,"dp")
        linear.addView(b)
    slot.addView(linear)
    return slot

def parser(risp): #recupero l'orario del/la docente/materia/aula cliccato/a nello slot
    global url_specifiche, url
    giorni = ["Lu", "Ma", "Me", "Gi", "Ve"]
    materie = {}
    day = 0
    lunghezza = 3
    for g in giorni:
        materie[g] = []
    cod = url_specifiche[risp] #recupero l'url del bottone cliccato nello slot e lo memorizzo in cod
    if cod.find("room") != -1 or cod.find("docente") != -1: #se ho cliccato un bottone di un'aula o di un docente i dettagli successivi saranno solo 2 
        lunghezza = 2
    try: #apro e leggo la pagina
        page = urllib2.urlopen(cod, timeout = 5)
        html = page.read()
        page.close()
    except IOError:
        output = rete_assente()
        return output
    soup = BeautifulSoup(html) #inizio il parsing
    righe = soup.tbody.findAll('tr')
    if(len(righe)!=5):
        raise classi.ErroreFormato
    for r in righe:
        slots = r.findAll('td')
        if(len(slots)!=4):
            raise classi.ErroreFormato()
        for i in range(4):
            t = slots[i].findAll(text=re.compile('\w'))
            tag = slots[i].findAll(href=re.compile('html'))
            if(tag is None):
                break
            else:
                for k in tag:
                    if k.contents[0] not in url.keys():
                        url[k.contents[0]] = 'http://orari.disit.unipmn.it/current' + k['href'].strip('..')
            if(len(t)<=0):
                raise classi.ErroreFormato()
            if len(t)==1:
                if(t[0]!="&nbsp;"):
                    raise classi.ErroreFormato()
                materie[giorni[day]].append(t[0])
            else: #devo controllare se ho cliccato un bottone con una materia (allora ci saranno 3 dettagli) o un bottone con aula/docente (allora ci saranno 2 dettagli)
                if lunghezza == 3:
                    if(len(t)%3!=0):
                        raise classi.ErroreFormato()
                else:
                    if(len(t)%2!=0):
                        raise classi.ErroreFormato()
                materie[giorni[day]].append("%".join(t) + ";")
        day = day + 1
    output = ""
    for g in giorni:
        output += g + "\n"
        for r in materie[g]:
            output += r + "\n"
    return output

def prima_navigazione(output, dip): #primo livello di navigazione (genero il primo orario e la prima finestra slot)
    while True:
        layout = generazione_orario(output, dip) #genero l'orario contenuto in output
        layout.show(droid)
        risposta = decisione(layout, 0, 1) #decido cosa fare nella schermata con l'orario
        if risposta == "fine0": #se schiaccio il bottone annulla o il tasto back ritorno alla schermata precedente
            return 0
        elif risposta == "fine1": #se schiaccio il bottone esci esco dall'applicazione
            return 1
        elif risposta == "stai":
            continue
        elif risposta == "partenza":
            return 2
        else: #se schiaccio uno dei bottoni nell'orario genero la finestra con i dettagli
            slot = finestra_slot(risposta, dip)
            while True:
                slot.show(droid)
                risposta = decisione(slot, 0, 1) #decido cosa fare nella finestra con i dettagli
                if risposta == "fine0":
                    break
                elif risposta == "fine1":
                    return 1
                elif risposta == "stai":
                    continue
                elif risposta == "partenza":
                    return 2
                else: #se schiaccio uno dei bottoni nella finestra entro nella funzione navigazione e genero un nuovo orario
                    nav = navigazione(risposta, dip)
                    if nav != 0:
                        return nav

def navigazione(risp, dip): #funzione di navigazione negli orari e nelle finestre (dopo la prima finestra slot creata)
    global cont #cont e' un contatore che mi tiene conto del numero di finestre aperte (se cont = 0 esco dalla funzione e torno alla prima finestra slot generata in prima_navigazione)
    finestre = {} #finestre e' un hash in cui memorizzo gli id di tutte le finestre nuove durante la navigazione
    slot_aperti = {} #slot_aperti e' un hash in cui memorizzo tutte le finestre aperte durante la navigazione
    finestre[cont] = risp #prima finestra (l'orario scelto durante prima_navigazione)
    salta = 2 #valore usato per muovermi nella navigazione a seguito dell'apertura del menu opzionale
    while True:
        if salta == 1 or salta == 2: #se non ho premuto il menu opzionale nello slot o l'ho premuto nell'orario procedo normalmente
            orario = parser(finestre[cont]) #recupero l'orario scelto corrispondente a risp 
            tabella = generazione_orario(orario, dip) #genero l'orario
            tabella.show(droid)
            risposta = decisione(tabella, 0, 1) #decido cosa fare nell'orario generato
            if risposta == "fine0": #se schiaccio il bottone ritorna o il tasto back controllo dove mi trovo nella navigazione
                salta = 0 #imposto questo valore perche' devo cambiare schermata
                cont = cont - 1
                if cont == 0: #se sono tornato all'inizio esco dalla funzione
                    break
                slot_aperti[cont].show(droid) #se sono in un punto intermedio della funzione riapro la finestra precedente a quella in cui mi trovavo
                ris = decisione(slot_aperti[cont], 0, 1) #decido ora cosa fare in questa finestra vecchia
            elif risposta == "fine1": #se schiaccio il bottone esci esco dall'applicazione indipendentemente dal punto in cui mi trovo
                return 1
            elif risposta == "partenza":
                return 2
            elif risposta == "stai":
                salta = 1 #imposto questo valore perche' devo rimanere nella schermata dell'orario
                continue
            else: #se schiaccio uno dei bottoni della finestra ne apro una nuova
                salta = 0 #imposto questo valore perche' devo cambiare schermata
                cont = cont + 1
                finestre[cont] = risposta #memorizzo in finestre la nuova finestra aperta
                slot = finestra_slot(finestre[cont], dip) #apro la finestra
                slot_aperti[cont] = slot #memorizzo la nuova finestra tra quelle gia' aperte in slot_aperti
                slot.show(droid)
                ris = decisione(slot, 0, 1) #decido cosa fare nella nuova finestra
        else: #altrimenti resto nello slot in cui ho premuto il menu opzionale
            salta = 0 #imposto questo valore perche' devo cambiare schermata
            slot = finestra_slot(finestre[cont], dip) #apro la finestra
            slot.show(droid)
            ris = decisione(slot, 0, 1) #decido cosa fare nella nuova finestra
        if salta == 0:
            if ris == "fine0": #se schiaccio il bottone ritorna o il tasto back torno indietro di una finestra (torno ad una finestra con l'orario)
                salta = 2 #imposto questo valore perche' devo cambiare schermata
                cont = cont - 1
            elif ris == "fine1": #se schiaccio il bottone esci esco dall'applicazione indipendentemente dal punto in cui mi trovo
                return 1
            elif ris == "partenza":
                return 2
            elif ris == "stai":
                salta = 3 #imposto questo valore perche' devo rimanere nella schermata dello slot
                continue
            else: #se schiaccio uno dei bottoni della finestra ne apro una nuova
                salta = 2 #imposto questo valore perche' devo cambiare schermata
                cont = cont + 1
                finestre[cont] = ris #memorizzo in finestre la nuova finestra aperta
    cont = 1
    return 0

def main():
    global cambiamenti, font_cambiato
    temp = {}
    stato = 0 #valore di controllo della funzione main
    stessa_applicazione = 0 #valore per gestire la schermata iniziale durante la stessa esecuzione dell'applicazione
    gia_scelto = 0 #valore per gestire il refresh delle pagine (evitando la seconda lettura del file)
    m = classi.Menu() 
    m.creazione_menu_opzionale(droid) #creo il menu opzionale
    while True:
        if stessa_applicazione == 0 and gia_scelto == 0: #se l'esecuzione dell'applicazione e' nuova e non ho già cambiato qualcosa nel menù
            try: #controllo nel file cambiamenti se avevo già selezionato un corso di laurea in un'esecuzione precedente dell'applicazione
                camb = classi.GestioneFile()
                temp = camb.lettura_file(classi.GestioneFile.file_cambiamenti)
                ris = temp['corso_laurea']
                if temp['font'] != "":
                    cambiamenti['font'] = temp['font']
                    font_cambiato = 1
                if ris == "": #se ho cambiato solo il font allora devo ripartire dalla schermata iniziale
                    inizio = schermata_iniziale()
                    inizio.show(droid)
                    ris = decisione(inizio, 1, 0) #decido cosa fare nella schermata iniziale
            except (EOFError, IOError): #altrimenti parto dalla schermata iniziale per la scelta del corso di laurea
                inizio = schermata_iniziale()
                inizio.show(droid)
                ris = decisione(inizio, 1, 0)
        else:
            inizio = schermata_iniziale()
            inizio.show(droid)
            ris = decisione(inizio, 1, 0)
        if ris == "fine0": #se schiaccio il tasto back o il bottone esci esco dall'applicazione
            break
        elif ris == "stai":
            gia_scelto = 1
            continue
        else:
            while True:
                cambiamenti["controllo_cambiamenti"] = 1
                cambiamenti["corso_laurea"] = ris #memorizzo il corso di laurea appena scelto per ripartire da qui la prossima esecuzione
                anno = schermata_scelta_tipo_orario(ris) #passo alla schermata in cui scegliere l'anno
                anno.show(droid)
                risposta = decisione(anno, 1, 1) #decido cosa fare nella schermata della scelta del tipo d'orario
                if risposta == "fine0": #se schiaccio il tasto back o il bottone ritorna torno a schermata_iniziale
                    stessa_applicazione = 1
                    break
                elif risposta == "fine1": #se schiaccio il bottone esci esco dall'applicazione
                    stato = 1
                elif risposta == "partenza": #se ho deciso di cambiare il corso di laurea devo tornare a schermata_iniziale
                    stessa_applicazione = 1
                    break
                elif risposta == "stai":
                    continue
                elif risposta == "per": #se schiaccio il tasto personalizzato passo alla funzione per creare l'orario personalizzato
                    stato = orario_personalizzato(classi.AssDipURL.url_dip, ris)
                else: #se schiaccio uno dei bottoni degli anni passo alla funzione che genera l'orario classico dell'anno premuto
                    stato = orario_singolo_anno(classi.AssDipURL.url_dip[risposta + ris], ris)
                if stato == 1 or stato == 2:
                    stessa_applicazione = 1
                    break
                else:
                    continue
        if stato == 1:
            break
    if cambiamenti["controllo_cambiamenti"] == 1:
        camb = classi.GestioneFile()
        camb.scrittura_file(cambiamenti, classi.GestioneFile.file_cambiamenti)
    if len(temp) == 0 or temp['corso_laurea'] == "":
        inizio.dismiss()
    else:
        anno.dismiss()
    return

main()

"""
L'applicazione si sviluppa su 4 livelli:
1° livello: funzione main che richiama o la funziona orario_personalizzato o la funzione orario_singolo_anno
2° livello: funzione orario_personalizzato/funzione orario_singolo_anno che richiamano la funzione prima_navigazione 
            che apre la prima finestra contenente l'orario e da cui si puo' aprire anche la prima finestra con i dettagli.
            Inoltre in questo livello si può passare anche alla funzione orario_esistente (ovviamente se esiste un orario
            gia' generato) attraverso la funzione orario_personalizzato e anch'essa, a sua volta, richiama la funzione navigazione
3° livello: funzione prima_navigazione appunto genera il primo orario e, se si clicca uno dei bottoni dell'orario, anche la prima
            finestra con i dettagli; da qui se si vuole proseguire con la navigazione, la funzione ne richiama un'altra,
            chiamata navigazione in cui si può continuare a navigare negli orari e negli slot.
4° livello: funzione navigazione in cui si aprono nuoeìve finestre con orari e dettagli alternate e da cui e' sempre possibile
            uscire o tornare indietro (se si torna indietro si ritorna alla prima finestra slot aperta in prima_navigazione)
            
Inoltre o creato diverse classi che gestiscono piu' cose nell'applicazione e le ho inserite tutte nel file classi.py per eliminare
tutte le stringhe esplicite e accorciare il codice
"""